package com.ztil.cmd;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;

/**
 * cmd.exe
 */
public class CMDUtils {
	private final static String CMD_EXE = "cmd.exe";

	public static void main(String[] args) throws Exception, IOException {
		executeCommand(CMD_EXE + " /C java -version");
	}

	/**
	 * Executes a command line command using Java's Process class.
	 * @param command
	 * A String representation of the command line to execute.
	 * @throws IOException 
	 * @throws UnsupportedEncodingException 
	 */
	public static void executeCommand(String command) throws UnsupportedEncodingException, IOException {
		String s = null;
		Process p = Runtime.getRuntime().exec(command);
		try (BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream(), "UTF8"));
				BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream(), "UTF8"))) {
			while ((s = stdInput.readLine()) != null) {
				System.out.println(s);
			}
			while ((s = stdError.readLine()) != null) {
				System.err.println(s);
			}
		}
	}

	/**
	 * 
	 * @author Mr.zyl
	 * @param cmdarray
	 * @return
	 */
	public static Process processExecutor(List<String> cmdarray) {
		ProcessBuilder processBuilder = new ProcessBuilder(cmdarray);
		processBuilder.redirectErrorStream(false);
		Process process = null;
		try {
			process = processBuilder.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return process;
	}

	public static Process processExecutor(List<String> cmdarray, String directory) {
		ProcessBuilder processBuilder = new ProcessBuilder(cmdarray);
		processBuilder.directory(new File(directory));
		processBuilder.redirectErrorStream(false);
		Process process = null;
		try {
			process = processBuilder.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return process;
	}

	public static Process processExecutor(List<String> cmdarray, String directory, boolean redirectErrorStream) {
		ProcessBuilder processBuilder = new ProcessBuilder(cmdarray);
		processBuilder.directory(new File(directory));
		processBuilder.redirectErrorStream(redirectErrorStream);
		Process process = null;
		try {
			process = processBuilder.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return process;
	}

	public static Process processExecutor(String[] cmdarray) {
		ProcessBuilder processBuilder = new ProcessBuilder(cmdarray);
		processBuilder.redirectErrorStream(false);
		Process process = null;
		try {
			process = processBuilder.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return process;
	}

	public static Process processExecutor(String[] cmdarray, String directory) {
		ProcessBuilder processBuilder = new ProcessBuilder(cmdarray);
		processBuilder.directory(new File(directory));
		processBuilder.redirectErrorStream(false);
		Process process = null;
		try {
			process = processBuilder.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return process;
	}

	public static Process processExecutor(String[] cmdarray, String directory, boolean redirectErrorStream) {
		ProcessBuilder processBuilder = new ProcessBuilder(cmdarray);
		processBuilder.directory(new File(directory));
		processBuilder.redirectErrorStream(redirectErrorStream);
		Process process = null;
		try {
			process = processBuilder.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return process;
	}

	public static Process processExecutor(String[] cmdarray, String[] envp, String dir) {
		Runtime runtime = Runtime.getRuntime();
		Process process = null;
		try {
			process = runtime.exec(cmdarray, envp, new File(dir));
		} catch (IOException e) {
			e.printStackTrace();
		}
		return process;
	}

	/**
	 * read process.getInputStream() and process.getErrorStream()
	 * 
	 * @author Mr.zyl
	 * @param inputStream
	 * @param out
	 * @throws IOException 
	 */
	public static String readProcess(InputStream inputStream) throws IOException {
		StringBuffer sb = new StringBuffer();
		try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "GBK"))) {
			String line;
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
				System.out.println(line);
			}
		}
		return sb.toString();
	}

	/**
	 * taskkill /f /im node.exe
	 * 
	 * @author Mr.zyl
	 * @param processName
	 * @return
	 * @throws IOException
	 */
	public static Process taskKill(String processName) throws IOException {
		String cmdarray = "TASKKILL /F /IM " + processName;
		Process process = Runtime.getRuntime().exec(cmdarray);
		return process;
	}

	/**
	 * 得到端口的PID
	 * @param port
	 * @return
	 * @throws IOException 
	 * @throws UnsupportedEncodingException 
	 */
	public static String getPID(String port) throws UnsupportedEncodingException, IOException {
		String[] cmdarray = { CMD_EXE, "/C", "NETSTAT -AON|FINDSTR", port };
		String directory = System.getProperty("user.dir");
		boolean redirectErrorStream = true;
		Process process = processExecutor(cmdarray, directory, redirectErrorStream);
		String line = null;
		String pId = null;
		try (BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"));) {
			line = br.readLine();
			String[] str = line.split("\\s");
			pId = str[str.length - 1];
		}
		return pId;
	}

	/**
	 * 根据PID得到进程名
	 * @param pid
	 * @return
	 * @throws IOException 
	 */
	public static String getProgramName(String pid) throws IOException {
		String programName = null;
		String[] args = new String[] { CMD_EXE, "/C", "TASKLIST|FINDSTR", pid };
		try (InputStream is = Runtime.getRuntime().exec(args).getInputStream();
				BufferedReader br = new BufferedReader(new InputStreamReader(is));) {
			String temp = br.readLine();
			if (temp != null) {
				String[] strs = temp.split("\\s");
				programName = strs[0];
			}
		}

		return programName;
	}

}
